home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / NACKEXP.ZIP / EXAMPLE1.C < prev    next >
Text File  |  1993-08-15  |  14KB  |  572 lines

  1. /******************* ( Animation Construction Kit 3D ) ***********************/
  2. /*               Example using the ACK engine                 */
  3. /*               Author: Lary Myers                     */
  4. /*****************************************************************************/
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <dos.h>
  9. #include <mem.h>
  10. #include <alloc.h>
  11. #include <io.h>
  12. #include <fcntl.h>
  13. #include <time.h>
  14. #include <string.h>
  15. #include <conio.h>
  16. #include <sys\stat.h>
  17.  
  18. #include "ack3d.h"
  19. #include "example1.h"
  20.  
  21.  
  22.     ACKENG        *ae;
  23.     MOUSE        mouse;
  24.  
  25.     char        *MapFileName = "EXAMPLE1.MAP";
  26.     char        *PictureFile = "EXAMPLE1.LBM";
  27.     char        *PalFile     = "EXAMPLE1.PAL";
  28.     UCHAR far   *OverlayPic;
  29.  
  30.     BMTABLE bmTable[] = {
  31.         1   ,TYPE_WALL        ,"swall16.bbm",
  32.         2   ,TYPE_WALL        ,"swall17.bbm",
  33.         3   ,TYPE_WALL        ,"swall18.bbm",
  34.         60  ,TYPE_WALL        ,"sdoor.bbm",
  35.         61  ,TYPE_WALL        ,"swall16.bbm",
  36.         62  ,TYPE_WALL        ,"sdoor.bbm",
  37.         1   ,TYPE_OBJECT    ,"sman1.bbm",
  38.         2   ,TYPE_OBJECT    ,"can1.bbm",
  39.         -1  ,-1            ,""            /* End of table */
  40.         };
  41.  
  42.  
  43.     ColorRange  ranges[64] = {
  44.                 16,16,
  45.                 32,16,
  46.                 48,16,
  47.                 64,16,
  48.                 80,16,
  49.                 96,8,
  50.                 104,8,
  51.                 112,8,
  52.                 120,8,
  53.                 128,8,
  54.                 136,8,
  55.                 144,8,
  56.                 152,8,
  57.                 160,8,
  58.                 168,8,
  59.                 176,8,
  60.                 184,8,
  61.                 192,16,
  62.                 208,16,
  63.                 224,8,
  64.                 232,8,
  65.                 0,0
  66.                 };
  67.  
  68.  
  69. /* Entry point for application */
  70. /****************************************************************************
  71. **                                       **
  72. ****************************************************************************/
  73. int main(void)
  74. {
  75.     int        result,done = 0;
  76.     int        i,j,Spin,SpinAngle;
  77.  
  78. result = AppInitialize();
  79.  
  80. if (result)
  81.     {
  82.     printf("Error initializing: ErrorCode = %d\n",result);
  83.     return(1);
  84.     }
  85.  
  86.  
  87. result = AppSetupEngine();
  88.  
  89. if (result)
  90.     {
  91.     printf("Error setting up ACK engine: ErrorCode = %d\n",result);
  92.     AckWrapUp(ae);
  93.     return(1);
  94.     }
  95.  
  96.  
  97. result = AppSetupOverlay();
  98.  
  99. if (result)
  100.     {
  101.     printf("Error loading overlay: ErrorCode = %d\n",result);
  102.     AckWrapUp(ae);
  103.     return(1);
  104.     }
  105.  
  106.  
  107. result = AppLoadBitmaps();
  108.  
  109. if (result)
  110.     {
  111.     printf("Error loading bitmaps: ErrorCode = %d\n",result);
  112.     AckWrapUp(ae);
  113.     return(1);
  114.     }
  115.  
  116. result = AppSetupObjects();
  117.  
  118. if (result)
  119.     {
  120.     printf("Error creating objects: ErrorCode = %d\n",result);
  121.     AckWrapUp(ae);
  122.     return(1);
  123.     }
  124.  
  125. result = AppSetGraphics();
  126.  
  127. if (result)
  128.     {
  129.     AckSetTextmode();
  130.     printf("Error loading palette: ErrorCode = %d\n",result);
  131.     AckWrapUp(ae);
  132.     return(1);
  133.     }
  134.  
  135. AppSetupPalRanges();
  136.  
  137. Spin = SpinAngle = 0;
  138.  
  139. /*---------------------------------------------------------------------------*
  140. *                                         *
  141. *----------------------------------------------------------------------------*/
  142.  
  143. /*---------------------------------------------------------------------------*
  144. * Main execution loop. Here we check for mouse movement and continuously     *
  145. * display the 3D screen. Escape will exit this loop.                 *
  146. *----------------------------------------------------------------------------*/
  147. while (!done)
  148.     {
  149.  
  150.  
  151. /*---------------------------------------------------------------------------*
  152. * Check if we have turned the POV with the mouse.                 *
  153. *----------------------------------------------------------------------------*/
  154.     if (Spin)
  155.     {
  156.     Spin >>= 1;
  157.     ae->PlayerAngle += SpinAngle;
  158.     if (ae->PlayerAngle >= INT_ANGLE_360)
  159.         ae->PlayerAngle -= INT_ANGLE_360;
  160.     if (ae->PlayerAngle < 0)
  161.         ae->PlayerAngle += INT_ANGLE_360;
  162.  
  163.     }
  164.  
  165. /*---------------------------------------------------------------------------*
  166. * See if any object animation is needed (none in this example)             *
  167. *----------------------------------------------------------------------------*/
  168.     AckCheckObjectMovement(ae);
  169.  
  170. /*---------------------------------------------------------------------------*
  171. * Build the 3D views and display both front and back views on the screen.    *
  172. *----------------------------------------------------------------------------*/
  173.     AppShow3D();
  174.  
  175.  
  176.     if (kbhit())
  177.     if (getch() == 27)  /* Check for the escape key */
  178.         break;
  179.  
  180.  
  181. /*---------------------------------------------------------------------------*
  182. * Get any mouse changes that may have occurred.                     *
  183. *----------------------------------------------------------------------------*/
  184.     CheckMouse(&mouse);
  185.  
  186.  
  187. /*---------------------------------------------------------------------------*
  188. * Turning left.                                     *
  189. *----------------------------------------------------------------------------*/
  190.     if (mouse.mdx < 0)
  191.     {
  192.     Spin = -mouse.mdx;
  193.     Spin >>= 3;
  194.     SpinAngle = -INT_ANGLE_2 * Spin;
  195.     Spin = 1;
  196.     }
  197.  
  198. /*---------------------------------------------------------------------------*
  199. * Turning right.                                 *
  200. *----------------------------------------------------------------------------*/
  201.     if (mouse.mdx > 0)
  202.     {
  203.     Spin = mouse.mdx;
  204.     Spin >>= 3;
  205.     SpinAngle = INT_ANGLE_2 * Spin;
  206.     Spin = 1;
  207.     }
  208.  
  209. /*---------------------------------------------------------------------------*
  210. * Moving forward.                                 *
  211. *----------------------------------------------------------------------------*/
  212.     if (mouse.mdy < 0)
  213.     {
  214.     i = -mouse.mdy;
  215.     i >>= 2;
  216.     i += 16;
  217.     AckMovePOV(ae,ae->PlayerAngle,i);
  218.     }
  219.  
  220. /*---------------------------------------------------------------------------*
  221. * Moving backward.                                 *
  222. *----------------------------------------------------------------------------*/
  223.     if (mouse.mdy > 0)
  224.     {
  225.     i = mouse.mdy;
  226.     i >>= 2;
  227.     i += 16;
  228.     j = ae->PlayerAngle + INT_ANGLE_180;
  229.     if (j >= INT_ANGLE_360)
  230.         j -= INT_ANGLE_360;
  231.  
  232.     AckMovePOV(ae,j,i);
  233.     }
  234.     }
  235.  
  236. AckWrapUp(ae);
  237.  
  238. AckSetTextmode();
  239.  
  240. return(0);
  241. }
  242.  
  243.  
  244. /****************************************************************************
  245. **                                       **
  246. ****************************************************************************/
  247. /* This could be a routine that the application uses to initialize things */
  248. int AppInitialize(void)
  249. {
  250.     int        result = 0;
  251.  
  252. if (mouse_installed() != -1)
  253.     {
  254.     printf("Mouse required to run.\n");
  255.     return(-2);
  256.     }
  257.  
  258. mouse_hide_cursor();
  259.  
  260. ae = malloc(sizeof(ACKENG));    /* We first get memory for the structure */
  261.  
  262. if (ae == NULL)            /* Whoops, we didn't get the memory */
  263.     return(-1);            /* So return an error */
  264.  
  265. memset(ae,0,sizeof(ACKENG));    /* Now we clear out the entire structure */
  266.  
  267. /* Perform other initialization here */
  268.  
  269. return(result);
  270. }
  271.  
  272. /****************************************************************************
  273. ** Perform the initial setup of the ACK engine. The parameters below tell  **
  274. ** the engine how big the viewport is going to be, etc. Next the map file  **
  275. ** is read in as well as a pre-drawn background buffer.               **
  276. **                                       **
  277. ** NOTE: Ceiling and floor colors are not really needed with this example. **
  278. **                                       **
  279. ****************************************************************************/
  280. int AppSetupEngine(void)
  281. {
  282.     int        result;
  283.  
  284. ae->WinStartX = VIEW_X;
  285. ae->WinStartY = VIEW_Y;                /* Plug in the size we want */
  286. ae->WinEndX   = VIEW_X1;            /* for our viewport        */
  287. ae->WinEndY   = VIEW_Y1;
  288.  
  289. ae->DoorSpeed    = DOORSPEED;
  290. ae->xPlayer    = PLAYER_X;            /* Setup intial coordinates */
  291. ae->yPlayer    = PLAYER_Y;            /* for the POV        */
  292. ae->PlayerAngle = PLAYER_ANGLE;
  293.  
  294. result = AckInitialize(ae);            /* Then initialize the engine! */
  295.  
  296. if (result)
  297.     return(result);                /* Error, so get out now    */
  298.  
  299. result = AckReadMapFile(ae,MapFileName);
  300.  
  301. if (result)
  302.     {
  303.     AckWrapUp(ae);
  304.     return(result);                /* Error, so get out now    */
  305.     }
  306.  
  307. ae->TopColor    = CEILING_COLOR;        /* Setup our colors for the */
  308. ae->BottomColor = FLOOR_COLOR;            /* background....        */
  309.  
  310. ae->LightFlag = SHADING_ON;            /* Yes, we want light shading */
  311.  
  312. /* Not using the default background */
  313. #if 0
  314. result = AckBuildBackground(ae);        /* Build the ceiling, floor      */
  315. #endif
  316.  
  317. if (ae->BkgdBuffer)
  318.     free(ae->BkgdBuffer);
  319.  
  320. ae->BkgdBuffer = AckReadiff("exback.lbm");
  321.  
  322. if (result)
  323.     AckWrapUp(ae);
  324.  
  325. return(result);                    /* 0 if no error, else errorcode */
  326. }
  327.  
  328. /****************************************************************************
  329. ** Read in the full screen picture.                       **
  330. **                                       **
  331. ****************************************************************************/
  332. int AppSetupOverlay(void)
  333. {
  334.     int        result = 0;
  335.  
  336. OverlayPic = AckReadiff(PictureFile);    /* Load a Deluxe Paint picture    */
  337.  
  338. if (OverlayPic == NULL)            /* Whoops, got a problem    */
  339.     return(-1);                /* So return with an error    */
  340.  
  341. /* Not using an overlay for this example */
  342. #if 0
  343. result = AckCreateOverlay(ae,&OverlayPic[4]);    /* Compile the overlay    */
  344. #endif
  345.  
  346. return(result);
  347. }
  348.  
  349. /****************************************************************************
  350. ** Using our table above, read in all the bitmaps needed for this example. **
  351. **                                       **
  352. ****************************************************************************/
  353. int AppLoadBitmaps(void)
  354. {
  355.     int        result;
  356.     int        i = 0;
  357.  
  358. while (bmTable[i].Number != -1)
  359.     {
  360.     result = AckLoadBitmap(ae,
  361.                bmTable[i].Number,
  362.                bmTable[i].Type,
  363.                bmTable[i].Name);
  364.  
  365.     if (result)                    /* Error during load */
  366.     break;                    /* so get out now    */
  367.  
  368.     i++;                    /* Next index in table */
  369.     }
  370.  
  371.  
  372. return(result);
  373. }
  374.  
  375. /****************************************************************************
  376. ** Call the ACK engine to initialize our objects. Each object can have more**
  377. ** than 1 bitmap associated with it.                       **
  378. ****************************************************************************/
  379. int AppSetupObjects(void)
  380. {
  381.     int        result;
  382.     UCHAR    BitmapNumbers[2];
  383.  
  384. ae->ObjList[1].Dir   = 0;    /* Direction doesn't matter */
  385. ae->ObjList[1].Speed = 0;    /* is a stationary object   */
  386.  
  387. BitmapNumbers[0] = 1;        /* Bitmap to use with object (spaceman) */
  388.  
  389. result = AckCreateObject(ae,1,1,BitmapNumbers);
  390.  
  391. if (result)            /* An error occurred */
  392.     return(result);        /* so get out now    */
  393.  
  394. ae->ObjList[2].Dir   = 0;    /* Again a direction is irrelavent */
  395. ae->ObjList[2].Speed = 0;    /* Because speed 0 is stationary   */
  396.  
  397. BitmapNumbers[0] = 2;        /* Bitmap to use (canister) */
  398.  
  399. result = AckCreateObject(ae,2,1,BitmapNumbers);
  400.  
  401. return(result);
  402. }
  403.  
  404. /****************************************************************************
  405. ** Go into normal VGA mode 13h graphics mode and display our full screen   **
  406. ** picture. Read in and set the palette we want to use.               **
  407. **                                       **
  408. ****************************************************************************/
  409. int AppSetGraphics(void)
  410. {
  411.     int        result;
  412.     UCHAR far *Video;
  413.  
  414.  
  415. AckSetVGAmode();    /* Go into graphics */
  416.  
  417. if (OverlayPic != NULL)
  418.     {
  419.     Video = MK_FP(0xA000,0);
  420.     memmove(Video,&OverlayPic[4],64000);
  421.     }
  422.  
  423. result = AckLoadAndSetPalette(PalFile);
  424.  
  425. return(result);
  426. }
  427.  
  428.  
  429. /****************************************************************************
  430. ** This routine sets up a range of palette values that ACK will use for       **
  431. ** light shading. The ranges[] table above demonstrates one form of these  **
  432. ** palette values.                               **
  433. ****************************************************************************/
  434. void AppSetupPalRanges(void)
  435. {
  436.     int    i,j,k,found;
  437.     int    rangenos;
  438.     UCHAR    plotcolor;
  439.  
  440. for (rangenos = 0; rangenos < 64; rangenos++)
  441.     {
  442.     if (ranges[rangenos].start == 0)
  443.     break;
  444.     }
  445.  
  446.  
  447. for ( i = 0;i<16;i++)
  448.     {
  449.     for (j=0;j<256;j++)
  450.     {
  451.     found = 0;
  452.     // find the range the color is in.
  453.     for ( k = 0; k < rangenos; k++ )
  454.         {
  455.         if (j >= ranges[k].start && j < ranges[k].start+ranges[k].length)
  456.         {
  457.         found = 1;
  458.         break;
  459.         }
  460.         }
  461.     if (found)
  462.         {
  463.         // add color + i;
  464.         // if color + i > color+range then plot color = 0;
  465.         // otherwise plotcolor = color+i
  466.         if (j+i >= ranges[k].start+ranges[k].length)
  467.            plotcolor = 0;
  468.         else
  469.            plotcolor = j+i;
  470.         }
  471.     else
  472.         {
  473.         plotcolor = j;
  474.         }
  475.     ae->PalTable[j+(i*256)] = plotcolor;
  476.     }
  477.     }
  478.  
  479.  
  480. }
  481.  
  482. /****************************************************************************
  483. ** Display both a front and back view of the POV. The user will essentially**
  484. ** have "eyes in the back of thier heads!".                   **
  485. **                                       **
  486. ****************************************************************************/
  487. void AppShow3D(void)
  488. {
  489.     int        row,angle,oldangle;
  490.     UINT    offset,offset1;
  491.     UINT    bufoffset;
  492.     UCHAR   far *Video;
  493.     UCHAR   far *Src;
  494.  
  495. /* Any preprocessing the application wishes to do can go here */
  496.  
  497. AckBuildView(ae);    /* Tell the ACK engine to construct the POV */
  498.  
  499. #if 0
  500. AckDisplayScreen(ae);    /* Display the POV on the video screen */
  501. #endif
  502.  
  503. bufoffset = (320*VIEW_Y) + VIEW_X;
  504. offset = (320*7) + 10;
  505. offset1 = (320*110)+10;
  506.  
  507. Video = MK_FP(0xA000,offset);
  508.  
  509. Src = ae->ScreenBuffer + bufoffset;
  510.  
  511. for (row = 7; row < 89; row++)
  512.     {
  513.     memmove(Video,Src,152);
  514.     Video += 320;
  515.     Src += 320;
  516.     }
  517.  
  518. oldangle = ae->PlayerAngle;
  519. angle = oldangle + INT_ANGLE_180;
  520. if (angle >= INT_ANGLE_360)
  521.     angle -= INT_ANGLE_360;
  522.  
  523. /* Set an angle 180 degrees from the current POV angle */
  524.  
  525. ae->PlayerAngle = angle;
  526.  
  527. /* Build a new view to display */
  528.  
  529. AckBuildView(ae);
  530.  
  531. Video = MK_FP(0xA000,offset1);
  532.  
  533. Src = ae->ScreenBuffer + bufoffset;
  534.  
  535. for (row = 110; row < 192; row++)
  536.     {
  537.     memmove(Video,Src,152);
  538.     Video += 320;
  539.     Src += 320;
  540.     }
  541.  
  542. ae->PlayerAngle = oldangle;
  543.  
  544. }
  545.  
  546. /****************************************************************************
  547. ** Check the current position of the mouse to see if any changes have       **
  548. ** occurred since the last time. These changes are then used to move the   **
  549. ** POV around the map.                               **
  550. ****************************************************************************/
  551. void CheckMouse(MOUSE *m)
  552. {
  553.     int        dx,dy;
  554.     int        x,y,buttons;
  555.  
  556. mouse_read_cursor(&buttons,&y,&x);
  557. dx = x - 160;
  558. dy = y - 120;
  559. m->mButtons = buttons;
  560. mouse_set_cursor(120,160);
  561.  
  562. if (abs(dy) > 10 && abs(dx) < 32)
  563.     dx >>= 2;
  564.  
  565. m->mdx = dx;
  566. m->mdy = dy;
  567.  
  568. }
  569.  
  570. /** End of text **/
  571.  
  572.